/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;

namespace DaveSexton.DocProject.Sandcastle.Configuration
{
	public sealed class SandcastleSection : ConfigurationSection, IDisposable
	{
		#region Public Properties
		[ConfigurationProperty("defaultPresentation", DefaultValue = "Visual Studio 2005", IsRequired = false)]
		[StringValidator(MinLength = 1)]
		public string DefaultPresentation
		{
			get
			{
				return ((settings.IsCommitted("defaultPresentation"))
					? settings.GetCommittedValue("defaultPresentation")
					: base["defaultPresentation"] as string);
			}
			set
			{
				if (value == null)
					throw new ArgumentNullException("value");

				settings["defaultPresentation"] = value;
			}
		}

		[ConfigurationProperty("documentationTags", IsRequired = true)]
		public DocumentationTagsElement DocumentationTags
		{
			get
			{
				return (DocumentationTagsElement) base["documentationTags"];
			}
		}

		/// <remarks>
		/// This settings is used to determine whether reflection data files should be generated for the .NET Framework assemblies
		/// if they haven't been generated already.  Since the files are stored in Sandcastle's installation directory, the value 
		/// of this property is not persisted in isolated storage.  Instead, it's persisted in DocProject's configuration file so that 
		/// a user can easily change its value.
		/// </remarks>
		[ConfigurationProperty("generateFrameworkReflectionData", DefaultValue = true, IsRequired = false)]
		public bool GenerateFrameworkReflectionData
		{
			get
			{
				return (bool) base["generateFrameworkReflectionData"];
			}
			set
			{
				base["generateFrameworkReflectionData"] = value;
			}
		}

		[ConfigurationProperty("paths", IsRequired = true)]
		public PathsElement Paths
		{
			get
			{
				return base["paths"] as PathsElement;
			}
		}

		[ConfigurationProperty("projectPaths", IsRequired = true)]
		public ProjectPathsElement ProjectPaths
		{
			get
			{
				return (ProjectPathsElement) base["projectPaths"];
			}
		}

		[ConfigurationProperty("presentations", IsRequired = true)]
		[ConfigurationCollection(typeof(Presentation), CollectionType = ConfigurationElementCollectionType.BasicMap)]
		public PresentationCollection Presentations
		{
			get
			{
				return (PresentationCollection) base["presentations"];
			}
		}

		[ConfigurationProperty("sandcastleConfigChanges", IsRequired = true)]
		[ConfigurationCollection(typeof(ConfigChangeElement), CollectionType = ConfigurationElementCollectionType.BasicMap)]
		public ConfigChangeElementCollection ConfigChanges
		{
			get
			{
				return (ConfigChangeElementCollection) base["sandcastleConfigChanges"];
			}
		}
		#endregion

		#region Private / Protected
		private readonly IsolatedSettingsDictionary<string, string> settings;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="SandcastleSection" /> class.
		/// </summary>
		public SandcastleSection()
		{
			settings = new IsolatedSettingsDictionary<string, string>(
				System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForAssembly(), GetType(),
				System.Globalization.CultureInfo.InvariantCulture, StringComparer.OrdinalIgnoreCase);
		}
		#endregion

		#region Methods
		public void SaveChanges()
		{
			settings.Save();
		}
		#endregion

		#region IDisposable Members
		/// <summary>
		/// Releases all resources used by an instance of the <see cref="SandcastleSection" /> class.
		/// </summary>
		/// <remarks>
		/// This method calls the virtual <see cref="Dispose(bool)" /> method, passing in <strong>true</strong>, and then suppresses 
		/// finalization of the instance.
		/// </remarks>
		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		/// <summary>
		/// Releases unmanaged resources before an instance of the <see cref="SandcastleSection" /> class is reclaimed by garbage collection.
		/// </summary>
		/// <remarks>
		/// This method releases unmanaged resources by calling the virtual <see cref="Dispose(bool)" /> method, passing in <strong>false</strong>.
		/// </remarks>
		~SandcastleSection()
		{
			Dispose(false);
		}

		/// <summary>
		/// Releases the unmanaged resources used by an instance of the <see cref="SandcastleSection" /> class and optionally releases the managed resources.
		/// </summary>
		/// <param name="disposing"><strong>true</strong> to release both managed and unmanaged resources; <strong>false</strong> to release only unmanaged resources.</param>
		private void Dispose(bool disposing)
		{
			if (disposing)
				settings.Dispose();
		}
		#endregion
	}
}
